package model

import (
	"database/sql"
	"github.com/jmoiron/sqlx"
	"github.com/pkg/errors"
	"zimuzu_cvn_web_api/config"
	"zimuzu_cvn_web_api/pkg/errno"
)

// 校验是否今天存在记录
func CheckTodayRecord(Date string) (records int, err error) {
	err = sqlx.Get(config.C.DB.DB, &records, "SELECT count(*) FROM mg_profit_list WHERE `date` = ?", Date)
	if err != nil {
		return 0, err
	}
	return records, nil
}

// 校验是否存在记录
func CheckProfitTotalData(Date string, Source int) (Id int64, err error) {
	err = sqlx.Get(config.C.DB.DB, &Id, "Select id from mg_profit_total where `date` = ? AND `source` = ?", Date, Source)
	if err != nil {
		return 0, err
	}
	if Id <= 0 {
		return 0, errno.RecordError
	}
	return Id, nil
}

// 校验是否有结算记录
func CheckNodePaymentRecord(Date string) (records int, err error) {
	err = sqlx.Get(config.C.DB.DB, &records, "SELECT count(*) FROM mg_node_payment WHERE `date` = ?", Date)
	if err != nil {
		return 0, err
	}
	if records <= 0 {
		return 0, errno.RecordError
	}
	return records, nil
}

// 收益明细列表
type ProfitListResponse struct {
	Id       int64   `db:"id" form:"id" json:"list_id"`
	Uid      int64   `db:"uid" form:"uid" json:"uid"`
	Date     string  `db:"date" form:"date" json:"date"`
	Flows    int64   `db:"flows" form:"flows" json:"flows"`
	NetFlows int64   `db:"net_flows" form:"net_flows" json:"net_flows"`
	Cvn      float64 `db:"cvn" form:"cvn" json:"cvn"`
	NetCvn   float64 `db:"net_cvn" form:"net_cvn" json:"net_cvn"`
	Rate     float64 `db:"rate" form:"rate" json:"rate"`
}

func GetProfitRecordById(Id int64) (res ProfitListResponse, err error) {
	err = sqlx.Get(config.C.DB.DB, &res, "Select id, uid, date From mg_profit_list Where id = ?", Id)
	if err != nil {
		return res, err
	}
	return res, nil
}

// 获取收益明细列表
func GetUserProfitListFromDB(Uid int64, page, pageSize int) (res []ProfitListResponse, err error) {
	start := (page - 1) * pageSize
	err = sqlx.Select(config.C.DB.DB, &res, "SELECT id, uid, `date`, flows, net_flows, cvn, net_cvn, rate FROM"+
		" mg_profit_list WHERE uid = ? order by `date` desc limit ?, ?", Uid, start, pageSize)
	if err != nil {
		return res, err
	}
	return res, nil
}

func GetUserProfitListCountDB(Uid int64) (res int, err error) {
	err = sqlx.Get(config.C.DB.DB, &res, "SELECT count(*) FROM mg_profit_list WHERE uid = ?", Uid)
	if err != nil {
		return res, err
	}
	return res, nil
}

// 写入收益列表数据
func AddUserProfitListDB(NetProfits NetProfitResponse, Date string) (err error) {
	rs := sqlx.MustExec(config.C.DB.DB, "INSERT INTO mg_profit_list (uid,`date`, flows, cvn, rate, net_flows, net_cvn) "+
		" SELECT uid, `date`, SUM(up), SUM(cvn), source_rate, ? AS net_flows, ? AS net_cvn FROM mg_node_payment "+
		" WHERE `date` = ? GROUP BY uid DESC", NetProfits.SourceFlows, NetProfits.SourceCvn, Date)
	r1, err := rs.LastInsertId()
	if err != nil {
		return err
	}
	if r1 > 0 {
		return nil
	}
	return errors.New("写入收益列表数据异常")
}

// 收益明细详情
type ProfitDetailResponse struct {
	Source      int     `db:"source" form:"source" json:"source"`
	Flows       int64   `db:"flows" form:"flows" json:"flows"`
	NetFlows    int64   `db:"net_flows" form:"net_flows" json:"net_flows"`
	Cvn         float64 `db:"cvn" form:"cvn" json:"cvn"`
	NetCvn      float64 `db:"net_cvn" form:"net_cvn" json:"net_cvn"`
	Rate        float64 `db:"rate" form:"rate" json:"rate"`
	NodeId      int64   `db:"node_id" form:"node_id" json:"node_id"`
	Name        string  `db:"name" form:"name" json:"name"`
	SuperNodeId int     `db:"super_node_id" form:"super_node_id" json:"super_node_id"`
	OnlineTime  int     `db:"online_time" form:"online_time" json:"online_time"`
	Status      int     `db:"status" form:"status" json:"status"`
}

// 获取收益明细列表
func GetUserProfitDetailByListIdFromDB(Uid int64, Date string) (res []ProfitDetailResponse, err error) {
	err = sqlx.Select(config.C.DB.DB, &res, "select t2.name, t1.node_id, source, up as flows, source_flows as net_flows,"+
		" cvn, source_cvn as net_cvn, source_rate  AS rate, super_node_id, t1.`status`, t1.online_time FROM "+
		" mg_node_payment as t1 left join mg_node as t2 on t1.node_id = t2.node_id AND t2.uid = ? "+
		" WHERE t1.uid = ? and `date` = ? group by node_id asc", Uid, Uid, Date)
	if err != nil {
		return res, err
	}
	return res, nil
}

// 获取用户昨日收益明细
type ProfitTotalDB struct {
	Date   string  `db:"date" form:"date" json:"date"`
	Source int     `db:"source" form:"source" json:"source"`
	Flows  float64 `db:"flows" form:"flows" json:"flows"`
	Cvn    float64 `db:"cvn" form:"cvn" json:"cvn"`
	Gbps   float64 `db:"gbps" form:"gbps" json:"gbps"`
}

func GetNetProfitList(date string) (res []ProfitTotalDB, err error) {

	err = sqlx.Select(config.C.DB.DB, &res, "SELECT date, source, flows, cvn, gbps FROM mg_profit_total WHERE `date`=?", date)
	if err != nil {
		if err == sql.ErrNoRows {
			return res, nil
		} else {
			return res, err
		}
	}
	return res, nil
}

type ProfitTotalParams struct {
	ID     int64   `json:"id" db:"id"`
	Date   string  `json:"date" db:"date"`
	Source int     `json:"source" db:"source"`
	Flows  int64   `json:"flows" db:"flows"`
	Cvn    float64 `json:"cvn" db:"cvn"`
	Gbps   float64 `json:"gbps" db:"gbps"`
}

// 获取收益线路数据
func GetProfitTotalDateBySource(Date string, Source int) (res ProfitTotalParams, err error) {
	db := config.C.DB.DB
	err = sqlx.Get(db, &res, "SELECT id,date,source,flows,cvn,gbps FROM mg_profit_total WHERE `date` =? AND source = ?", Date, Source)
	if err != nil {
		return res, err
	}
	return res, nil
}

// 收益总线路数据
// 新增记录
func AddProfitTotalData(params ProfitTotalParams) (err error) {

	// 确认是否存在重复数据
	checkId, err := CheckProfitTotalData(params.Date, params.Source)
	if err == nil {
		return errno.ExistsRecord
	}
	if checkId > 0 {
		return errno.ExistsRecord
	}
	// 数据不存在，插入数据库
	res := sqlx.MustExec(config.C.DB.DB, "INSERT INTO mg_profit_total (`date`, `source`, `flows`, `cvn`, `gbps`) "+
		" Values (?, ?, ?, ?, ?)", params.Date, params.Source, params.Flows, params.Cvn, params.Gbps)
	r1, err := res.LastInsertId()
	if err != nil {
		return err
	}
	if r1 <= 0 {
		return errno.RecordError
	}
	return nil
}

type MultipleNodePaymentResponse struct {
	Name         string  `json:"name" db:"name"`
	Date         string  `json:"-" db:"date"`
	SuperNodeId  int64   `json:"-" db:"super_node_id"`
	Up           float64 `json:"flow" db:"up"`
	Cvn          float64 `json:"cvn" db:"cvn"`
	SuperCvn     float64 `json:"-" db:"super_cvn"`
	PledgeStatus int     `json:"pledge_status" db:"pledge_status"`
	SettleStatus int     `json:"settle_status" db:"settle_status"`
	Status       int     `json:"status" db:"status"`
	OnlineTime   int     `json:"online" db:"online_time"`
	Uid          int64   `json:"-" db:"uid"`
	NodeId       int64   `json:"node_id" db:"node_id"`
	Type         int     `json:"-" db:"type"`
	Source       int     `json:"-" db:"source"`
	SourceFlows  float64 `json:"net_flow" db:"source_flows"`
	SourceCvn    float64 `json:"net_cvn" db:"source_cvn"`
	SourceRate   float64 `json:"rate" db:"source_rate"`
}

// 批量节点质押&解除
type TheDateNodePaymentParams struct {
	Source int    `form:"source" json:"source"`
	Date   string `form:"date" json:"date"`
	PageParams
}

// 获取用户指定日期的结算记录
func GetUserTheDateNodePayment(Uid int64, Source int, Date string, Page, Per int) (res []MultipleNodePaymentResponse, err error) {
	start := (Page - 1) * Per
	err = sqlx.Select(config.C.DB.DB, &res, "Select 0 as settle_status,t2.name,t1.node_id,t1.up,t1.pledge_status,"+
		" t1.status,ROUND(t1.cvn, 2) as cvn, t1.super_node_id,t1.online_time,t1.source_flows,t1.source_rate "+
		" FROM mg_node_payment as t1 left join mg_node as t2 on t1.node_id = t2.node_id where t1.uid =? and "+
		" t1.source = ? and t1.`date`= ? ORDER by node_id ASC LIMIT ?, ?", Uid, Source, Date, start, Per)
	if err == sql.ErrNoRows {
		return res, nil
	}
	if err != nil {
		return res, err
	}
	return res, nil
}

// 获取指定日期是否已结算
func GetUserPaymentByDate(Uid int64, Date string) (status int, err error) {
	err = sqlx.Get(config.C.DB.DB, &status, "SELECT status FROM mg_user_payment WHERE uid = ? AND `date` =? LIMIT 1 ", Uid, Date)
	if err != nil {
		return 0, nil
	}
	return status, nil
}

// 获取昨日收益数据
type LastProfitDataResponse struct {
	Cvn   float64 `json:"cvn"`
	Flows float64 `json:"flows"`
}

func GetProfitListByUid(Uid int64, Date string) (profit LastProfitDataResponse, err error) {
	db := config.C.DB.DB
	err = sqlx.Get(db, &profit, "SELECT IFNULL( sum(cvn), 0.00) as cvn, IFNULL( SUM(flows), 0.00) as flows "+
		" FROM mg_profit_list WHERE uid = ? and `date` =? ", Uid, Date)
	if err != nil {
		return profit, err
	}
	return profit, nil
}
